﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace GP2D3D_Huiswerk2_RickBeijer_S1012261
{
    public class Projectile : GameComponent
    {
        private static readonly Vector3 GRAVITY = new Vector3(0, 0.5f, 0);
        private static List<KeyValuePair<Vector2, Rectangle>> frames;
        private int currentFrame;
        private float stepDistance;
        private float distance;
        private int updates;

        public Point Location
        {
            get;
            set;
        }

        public Texture2D Image
        {
            get;
            set;
        }

        public Vector3 Velocity
        {
            get;
            set;
        }

        public Rectangle CurrentFrame
        {
            get { return frames[currentFrame].Value; }
        }

        public Vector2 CurrentOrigin
        {
            get { return frames[currentFrame].Key; }
        }

        public Projectile(Game game, Point location, Texture2D image, Vector3 velocity)
            : base(game)
        {
            this.currentFrame = 29;
            this.stepDistance = (float)Math.Sqrt(velocity.X * velocity.X + velocity.Y * velocity.Y);
            this.distance = 0;
            this.Location = location;
            this.Image = image;
            this.Velocity = velocity;

            if (frames == null)
            {
                frames = new List<KeyValuePair<Vector2, Rectangle>>();
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(0, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(17, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(34, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(51, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(68, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(85, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(102, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(119, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(136, 0, 13, 15)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(155, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(172, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(189, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(206, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(223, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(240, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(257, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(274, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(291, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(308, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(325, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(342, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(359, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(376, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(393, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(410, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(427, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(444, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(461, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(478, 0, 13, 13)));
                frames.Add(new KeyValuePair<Vector2, Rectangle>(new Vector2(7.5f, 7.5f), new Rectangle(495, 0, 13, 13)));
            }
        }

        public override void Update(GameTime gameTime)
        {
            // Don't change the image every update.
            updates++;

            if (updates > 100)
            {
                updates = 0;
            }

            // Keep animating, but not every update
            if (updates % 2 == 0)
            {
                currentFrame--;

                // Move the projectile along its trajectory
                Location = new Point(Location.X + (int)(Velocity.X + 0.5), Location.Y + (int)(Velocity.Y + 0.5));
                // Add the distance the projectile traveled, so that we can stop it when it goes too far
                distance += stepDistance;
                // Add the GRAVITY to the current velocity, this will make a new velocity (direction and speed)
                Velocity += GRAVITY;
            }

            // If we have not yet reached the max distance for this projectile to travel, just keep animating
            if (distance <= 100)
            {
                // If we have run out of "just flying" frames, return to the first frame
                if ( currentFrame <= 8 )
                {
                    currentFrame = 29;
                }
            }
            else
            {
                // If the we have run out of "almost exploding" frames, let the ProjectileList know
                if (currentFrame < 0)
                {
                    // Make sure the current frame never drops below 0
                    currentFrame = 0;

                    // Let the ProjectileList know that this projectile has to explode
                    ((IProjectileList)Game.Services.GetService(typeof(IProjectileList))).RemoveProjectile(this);
                }
            }

            base.Update(gameTime);
        }
    }
}